import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/foundation.dart';
import '../../data/models/note_model.dart';
import '../../data/models/project_model.dart';
import '../../data/models/todo_model.dart';

/// 离线操作类型枚举
enum OfflineOperationType {
  create,
  update,
  delete,
}

/// 离线操作记录
class OfflineOperation {
  final String id;
  final String entityType;
  final OfflineOperationType operationType;
  final Map<String, dynamic> data;
  final DateTime timestamp;

  OfflineOperation({
    required this.id,
    required this.entityType,
    required this.operationType,
    required this.data,
    required this.timestamp,
  });

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'entityType': entityType,
      'operationType': operationType.name,
      'data': data,
      'timestamp': timestamp.toIso8601String(),
    };
  }

  factory OfflineOperation.fromJson(Map<String, dynamic> json) {
    return OfflineOperation(
      id: json['id'] as String,
      entityType: json['entityType'] as String,
      operationType: OfflineOperationType.values.firstWhere(
        (type) => type.name == json['operationType'],
        orElse: () => OfflineOperationType.create,
      ),
      data: json['data'] as Map<String, dynamic>,
      timestamp: DateTime.parse(json['timestamp'] as String),
    );
  }
}

/// 离线数据管理器
class OfflineDataManager {
  static final OfflineDataManager _instance = OfflineDataManager._internal();
  factory OfflineDataManager() => _instance;
  OfflineDataManager._internal();

  static const String _offlineOperationsKey = 'offline_operations';

  /// 保存离线操作记录
  Future<void> saveOfflineOperation(OfflineOperation operation) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final operations = await getOfflineOperations();

      // 添加新的操作记录
      operations.add(operation);

      // 序列化并保存
      final operationsJson = operations.map((op) => op.toJson()).toList();
      final jsonString = json.encode(operationsJson);
      await prefs.setString(_offlineOperationsKey, jsonString);
    } catch (e) {
      debugPrint('保存离线操作记录失败: $e');
      rethrow;
    }
  }

  /// 获取所有离线操作记录
  Future<List<OfflineOperation>> getOfflineOperations() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final jsonString = prefs.getString(_offlineOperationsKey);

      if (jsonString == null) {
        return [];
      }

      final List<dynamic> operationsJson = json.decode(jsonString);
      return operationsJson
          .map(
              (json) => OfflineOperation.fromJson(json as Map<String, dynamic>))
          .toList();
    } catch (e) {
      debugPrint('获取离线操作记录失败: $e');
      return [];
    }
  }

  /// 根据实体类型获取离线操作记录
  Future<List<OfflineOperation>> getOfflineOperationsByType(
      String entityType) async {
    final operations = await getOfflineOperations();
    return operations.where((op) => op.entityType == entityType).toList();
  }

  /// 删除已同步的操作记录
  Future<void> removeSyncedOperations(List<String> operationIds) async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final operations = await getOfflineOperations();

      // 移除已同步的操作
      operations.removeWhere((op) => operationIds.contains(op.id));

      // 序列化并保存
      final operationsJson = operations.map((op) => op.toJson()).toList();
      final jsonString = json.encode(operationsJson);
      await prefs.setString(_offlineOperationsKey, jsonString);
    } catch (e) {
      debugPrint('删除已同步操作记录失败: $e');
      rethrow;
    }
  }

  /// 清空所有离线操作记录
  Future<void> clearAllOperations() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.remove(_offlineOperationsKey);
    } catch (e) {
      debugPrint('清空离线操作记录失败: $e');
      rethrow;
    }
  }

  /// 为笔记创建离线操作记录
  Future<void> createNoteOfflineOperation(NoteCreateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_${request.title}',
      entityType: 'note',
      operationType: OfflineOperationType.create,
      data: {
        'title': request.title,
        'content': request.content,
        'noteType': request.noteType.code,
        'tags': request.tags,
        'authorId': request.authorId,
        'isPublic': request.isPublic,
        'projectId': request.projectId,
        'todoId': request.todoId,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为项目创建离线操作记录
  Future<void> createProjectOfflineOperation(
      ProjectCreateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_${request.projectName}',
      entityType: 'project',
      operationType: OfflineOperationType.create,
      data: {
        'projectName': request.projectName,
        'description': request.description,
        'priority': request.priority.code,
        'deadline': request.deadline?.toIso8601String(),
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为待办创建离线操作记录
  Future<void> createTodoOfflineOperation(TodoCreateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_${request.title}',
      entityType: 'todo',
      operationType: OfflineOperationType.create,
      data: {
        'projectId': request.projectId,
        'title': request.title,
        'description': request.description,
        'priority': request.priority.code,
        'todoType': request.todoType.code,
        'assigneeId': request.assigneeId,
        'dueDate': request.dueDate?.toIso8601String(),
        'estimatedHours': request.estimatedHours,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为笔记更新离线操作记录
  Future<void> updateNoteOfflineOperation(
      int noteId, NoteUpdateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$noteId',
      entityType: 'note',
      operationType: OfflineOperationType.update,
      data: {
        'id': noteId,
        if (request.title != null) 'title': request.title,
        if (request.content != null) 'content': request.content,
        if (request.noteType != null) 'noteType': request.noteType!.code,
        if (request.tags != null) 'tags': request.tags,
        if (request.isPublic != null) 'isPublic': request.isPublic,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为项目更新离线操作记录
  Future<void> updateProjectOfflineOperation(
      int projectId, ProjectUpdateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$projectId',
      entityType: 'project',
      operationType: OfflineOperationType.update,
      data: {
        'id': projectId,
        if (request.projectName != null) 'projectName': request.projectName,
        if (request.description != null) 'description': request.description,
        if (request.status != null) 'status': request.status!.code,
        if (request.priority != null) 'priority': request.priority!.code,
        if (request.deadline != null)
          'deadline': request.deadline!.toIso8601String(),
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为待办更新离线操作记录
  Future<void> updateTodoOfflineOperation(
      int todoId, TodoUpdateRequest request) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$todoId',
      entityType: 'todo',
      operationType: OfflineOperationType.update,
      data: {
        'id': todoId,
        if (request.title != null) 'title': request.title,
        if (request.description != null) 'description': request.description,
        if (request.status != null) 'status': request.status!.code,
        if (request.priority != null) 'priority': request.priority!.code,
        if (request.todoType != null) 'todoType': request.todoType!.code,
        if (request.assigneeId != null) 'assigneeId': request.assigneeId,
        if (request.dueDate != null)
          'dueDate': request.dueDate!.toIso8601String(),
        if (request.estimatedHours != null)
          'estimatedHours': request.estimatedHours,
        if (request.actualHours != null) 'actualHours': request.actualHours,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为笔记删除离线操作记录
  Future<void> deleteNoteOfflineOperation(int noteId) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$noteId',
      entityType: 'note',
      operationType: OfflineOperationType.delete,
      data: {
        'id': noteId,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为项目删除离线操作记录
  Future<void> deleteProjectOfflineOperation(int projectId) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$projectId',
      entityType: 'project',
      operationType: OfflineOperationType.delete,
      data: {
        'id': projectId,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }

  /// 为待办删除离线操作记录
  Future<void> deleteTodoOfflineOperation(int todoId) async {
    final operation = OfflineOperation(
      id: '${DateTime.now().millisecondsSinceEpoch}_$todoId',
      entityType: 'todo',
      operationType: OfflineOperationType.delete,
      data: {
        'id': todoId,
      },
      timestamp: DateTime.now(),
    );

    await saveOfflineOperation(operation);
  }
}
